# coding : UTF-8
"""
author：BingBO   time：2022.11.11
Theme：
notes：
"""
import cv2 as cv
import numpy as np
import moduleCommon as Com


def LaserExtract(src, mode):
    print("****************** Laser%dExtract ******************" % mode)
    _, _, red = cv.split(src)
    _, binary = cv.threshold(red, 195, 255, cv.THRESH_BINARY)
    binary = cv.medianBlur(binary, 3)
    cv.imshow('binaryL%d' % mode, binary)
    cv.imwrite(r"F:\MVS_Data\binaryLaser%d.jpg" % mode, binary)
    hight, width = binary.shape[:2]

    # 计算光条数量的方法不适合Square，在焊缝处的工件上会有激光残影存在
    # 轮廓近似方法：cv.CHAIN_APPROX_SIMPLE  cv.CHAIN_APPROX_NONE：存储所有的轮廓点
    contours, _ = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE)  # 耗内存
    print("轮廓个数:", len(contours))  # 轮廓的个数
    # 当轮廓面积<阈值，将该轮廓用0填充
    for i in range(len(contours)):
        area = cv.contourArea(contours[i])  # 轮廓面积
        print(area)
        if area < 100:
            cv.drawContours(binary, [contours[i]], 0, 0, -1)
    cv.imshow('remove%d' % mode, binary)

    # 对全局阈值检测最大间隙
    gapMaxIdxS1, gapMaxIdxL1 = Com.gapDetection(binary, 0, 0)
    d1 = gapMaxIdxL1 - gapMaxIdxS1
    # 对工件阈值检测最大间隙
    binaryWeldment = binary[:, 0:int(gapMaxIdxS1 + d1 / 2)]
    gapMaxIdxS2, gapMaxIdxL2 = Com.gapDetection(binaryWeldment, 0, 0)
    d2 = gapMaxIdxL2 - gapMaxIdxS2

    binaryLeft = binary[:, 0:int(gapMaxIdxS2 + d2 / 2)]
    binaryRight = binary[:, int(gapMaxIdxS2 + d2 / 2):int(gapMaxIdxS1 + d1 / 2)]

    cv.imshow('binaryLeft%d' % mode, binaryLeft)
    cv.imshow('binaryRight%d' % mode, binaryRight)

    # 垂直COG  binaryRight  求工件边界点
    sumx, sumy = 0, 0
    for row in range(hight):  # 遍历这一行的每一列
        sumx += binaryWeldment[row, gapMaxIdxS1]
        sumy += binaryWeldment[row, gapMaxIdxS1] * (row + 1)  # 重心在第几列
    if sumx != 0:
        indexRow = int(sumy / sumx) - 1  # 化为坐标索引
    edgePoint = [indexRow, gapMaxIdxS1]
    print("Laser%d工件边界特征点：" % mode, edgePoint)
    src[indexRow, gapMaxIdxS1] = [255, 0, 0]

    sumY = np.sum(binaryRight, axis=1)  # 0列 1行
    sumYIndex = np.where(sumY != 0)  # 返回索引numpy数组和元素类型的元组
    if mode == 2:  # 右上条纹
        rowDnIdx = max(sumYIndex[0])
    if mode == 1:  # 左上条纹
        rowDnIdx = min(sumYIndex[0])

    sumx, sumy = 0, 0
    for col in range(binaryWeldment.shape[1]):  # 遍历这一行的每一列
        sumx += binaryWeldment[rowDnIdx, col]
        sumy += binaryWeldment[rowDnIdx, col] * (col + 1)  # 重心在第几列
    if sumx != 0:
        indexCol = int((sumy / sumx) - 1)  # 化为坐标索引
    featureP1 = [rowDnIdx, indexCol]
    src[rowDnIdx, indexCol] = [255, 0, 0]

    sumY = np.sum(binaryLeft, axis=1)  # 0列 1行
    sumYIndex = np.where(sumY != 0)  # 返回索引numpy数组和元素类型的元组
    if mode == 2:  # 右上条纹
        rowUpIdx = min(sumYIndex[0])
    if mode == 1:  # 左上条纹
        rowUpIdx = max(sumYIndex[0])

    sumx, sumy = 0, 0
    for col in range(binaryLeft.shape[1]):  # 遍历这一行的每一列
        sumx += binaryLeft[rowUpIdx, col]
        sumy += binaryLeft[rowUpIdx, col] * (col + 1)  # 重心在第几列
    if sumx != 0:
        indexCol = int((sumy / sumx) - 1)  # 化为坐标索引

    featureP2 = [rowUpIdx, indexCol]
    src[rowUpIdx, indexCol] = [255, 0, 0]

    # 计算焊缝中点
    featurePmid = [int((featureP1[0] + featureP2[0]) / 2),
                   int((featureP1[1] + featureP2[1]) / 2)]
    print("焊缝中点特征点%d：" % mode, featurePmid)
    src[int((featureP1[0] + featureP2[0]) / 2),
        int((featureP1[1] + featureP2[1]) / 2)] = [255, 0, 0]

    cv.imshow('featurePoint%d' % mode, src)
    cv.imwrite(r"F:\MVS_Data\featurePoint%d.png" % mode, src)

    return featurePmid, edgePoint
